﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Web;
using System.Web.UI;
using Microsoft.Reporting.WebForms;
using SoftSource.Timecard.Web.DAL;
using SoftSource.Timecard.Web.Data;
using SoftSource.Timecard.Web.Library;

namespace SoftSource.Timecard.Web
{
    public partial class ReportViewer : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            this.LoadReport(this.Request);
        }

        private DateTime GetDateParameter(string name, NameValueCollection nvc)
        {
            return this.GetParameterValue<DateTime>(name, nvc, DateTime.Parse);
        }

        private T GetParameterValue<T>(string name, NameValueCollection nvc, Func<string, T> parser)
        {
            var parameter = nvc[name];

            if (parameter != null)
            {
                return parser(parameter);
            }
            else
            {
                return default(T);
            }
        }

        private void LoadReport(HttpRequest request)
        {
            string reportName = request.QueryString["ReportName"];
            object data = null;
            List<ReportParameter> reportParameters = new List<ReportParameter>();            
            
            switch (reportName)
            {
                case "CostofServices":
                    {
                        DateTime startDate = this.GetDateParameter("StartDate", request.QueryString);
                        DateTime endDate = this.GetDateParameter("EndDate", request.QueryString);

                        data = Reports.GetCostOfServicesData(
                            startDate,
                            endDate);
                        break;
                    }
                case "CustomerSummary":
                    data = Reports.GetCustomerSummaryData(this.GetParameterValue<int>("CustomerID", request.QueryString, int.Parse));
                    break;
                case "EmployeeTravel":
                    {
                        DateTime startDate = this.GetDateParameter("StartDate", request.QueryString);
                        DateTime endDate = this.GetDateParameter("EndDate", request.QueryString);

                        data = Reports.GetEmployeeTravelData(
                            startDate,
                            endDate);

                        reportParameters.Add(new ReportParameter("startDate", startDate.ToShortDateString()));
                        reportParameters.Add(new ReportParameter("endDate", endDate.ToShortDateString()));
                        break;
                    }
                case "EngineeringBonus":
                    break;
                case "EntriesPastDue":
                    data = Reports.GetEntriesPastDueData();
                    break;
                case "InvoiceByPerson":
                    {
                        var date = this.GetDateParameter("Date", request.QueryString);
                        data = Reports.GetInvoiceByPersonData(date);

                        reportParameters.Add(new ReportParameter("EndDate", date.ToShortDateString()));
                    }
                    break;
                case "InvoiceByPersonForProject":
                    {
                        Project project = Projects.GetProjectByID(this.GetParameterValue<int>("ProjectID", request.QueryString, int.Parse));
                        DateTime endDate = this.GetDateParameter("EndDate", request.QueryString);

                        data = Reports.GetInvoiceByPersonForProjectData(
                            project.Name,
                            endDate);

                        reportParameters.Add(new ReportParameter("EndDate", endDate.ToShortDateString()));
                        reportParameters.Add(new ReportParameter("ProjectName", project.Name));
                        break;
                    }
                case "InvoiceByPersonForProjectAnyBillStatus":
                    {
                        Project project = Projects.GetProjectByID(this.GetParameterValue<int>("ProjectID", request.QueryString, int.Parse));
                        DateTime startDate = this.GetDateParameter("StartDate", request.QueryString);
                        DateTime endDate = this.GetDateParameter("EndDate", request.QueryString);

                        data = Reports.GetInvoiceByPersonForProjectWithAnyBillStatusData(
                            project.Name,
                            startDate,
                            endDate);

                        reportParameters.Add(new ReportParameter("StartDate", startDate.ToShortDateString()));
                        reportParameters.Add(new ReportParameter("EndDate", endDate.ToShortDateString()));
                        reportParameters.Add(new ReportParameter("ProjectName", project.Name));
                        break;
                    }
                case "LastEntry":
                    data = Reports.GetLastEntryData();
                    break;
                case "ProjectsWithInvalidManagers":
                    data = Reports.GetProjectsWithInvalidManagersData();
                    break;
                case "ProjectSummary":
                    {
                        int projectID = this.GetParameterValue<int>("ProjectID", request.QueryString, int.Parse);
                        DateTime startDate = this.GetDateParameter("StartDate", request.QueryString);
                        DateTime endDate = this.GetDateParameter("EndDate", request.QueryString);

                        data = Reports.GetProjectSummaryData(projectID, startDate, endDate);

                        reportParameters.Add(new ReportParameter("StartDate", startDate.ToShortDateString()));
                        reportParameters.Add(new ReportParameter("EndDate", endDate.ToShortDateString()));
                        break;
                    }
                case "PTODetail":
                    data = Reports.GetPTODetailData(
                        this.GetDateParameter("StartDate", request.QueryString),
                        this.GetDateParameter("EndDate", request.QueryString));
                    break;
                case "PTOSummary":
                    data = Reports.GetPTOSummaryData(
                        this.GetDateParameter("StartDate", request.QueryString),
                        this.GetDateParameter("EndDate", request.QueryString));
                    break;
                case "PTOUser":
                    data = Reports.GetPTOUserData(
                        Users.GetUserByID(this.GetParameterValue<int>("UserID", request.QueryString, int.Parse)).UserName,
                        this.GetDateParameter("StartDate", request.QueryString),
                        this.GetDateParameter("EndDate", request.QueryString));
                    break;
                case "UnapprovedEntries":                    
                        data = Reports.GetUnapprovedEntriesData();
                        break;
                case "Utilization":
                    {
                        DateTime startDate = this.GetDateParameter("StartDate", request.QueryString);
                        DateTime endDate = this.GetDateParameter("EndDate", request.QueryString);
                        int workDays = this.GetWorkDays(startDate, endDate);

                        ReportParameter workDaysParameter = new ReportParameter("WorkDays", workDays.ToString());
                        reportParameters.Add(workDaysParameter);

                        data = Reports.GetUtilizationData(
                            this.GetDateParameter("StartDate", request.QueryString),
                            this.GetDateParameter("EndDate", request.QueryString));
                        break;
                    }
                case "WeeklySummary":
                    {
                        DateTime startDate = this.GetDateParameter("Date", request.QueryString)
                                .StartOfWeek(DayOfWeek.Sunday);

                        data = Reports.GetWeeklySummaryData(startDate);

                        reportParameters.Add(new ReportParameter("StartDate", startDate.ToShortDateString()));
                        reportParameters.Add(new ReportParameter("EndDate", startDate.AddDays(7).ToShortDateString()));
                        break;
                    }
                case "WRQSummary":
                    data = Reports.GetWRQSummaryData();
                    break;
                default:
                    break;
            }

            if (data != null)
            {
                this.LoadRDLC(reportName, data, reportParameters);
            }
            else
            {
            }
        }

        private int GetWorkDays(DateTime start, DateTime end)
        {
            int counter = 0;

            for (DateTime currDate = start; currDate <= end; currDate = currDate.AddDays(1))
            {
                if (currDate.DayOfWeek != DayOfWeek.Saturday && currDate.DayOfWeek != DayOfWeek.Sunday)
                {
                    counter++;
                }
            }
            return counter;
        }

        private void LoadRDLC(string reportName, object dataSource, List<ReportParameter> reportParameters)
        {
            string root = this.Server.MapPath(".");
            string path = @"Report Files\{0}.rdlc";

            path = Path.Combine(root, path);
            path = string.Format(path, reportName);
            var reportViewer = this.ReportViewer1;

            reportViewer.Visible = true;
            reportViewer.LocalReport.ReportPath = path;

            reportViewer.LocalReport.DataSources.Clear();
            reportViewer.LocalReport.DataSources.Add(new ReportDataSource(reportName, dataSource));


            List<ReportParameter> parameters = new List<ReportParameter>();
            parameters.AddRange(reportParameters);

            if (parameters != null)
            {
                reportViewer.LocalReport.SetParameters(parameters);
            }

            reportViewer.LocalReport.Refresh();
        }
    }
}
